﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EventReminder.Common;
using EventReminder.Client.EventReminderServiceRef;
using System.Security.Authentication;

namespace EventReminder.Client
{
    class EventReminderController
    {
        private EventReminderModel _model;
        private MonthForm _month;
        private LoginDialog _login;
        private string _userName;

        private EventData _modifyingEvent;

        #region Events (Observer)
        public event EventHandler<EventsUpdatedArgs> EventsUpdated
        {
            add { _model.EventsUpdated += value; }
            remove { _model.EventsUpdated -= value; }
        }

        public event EventHandler LoginSucceeded
        {
            add { _model.LoginSucceeded += value; }
            remove { _model.LoginSucceeded -= value; }
        }

        public event EventHandler LoginFailed
        {
            add { _model.LoginFailed += value; }
            remove { _model.LoginFailed -= value; }
        }

        public event EventHandler LogoutSucceeded
        {
            add { _model.LogoutSucceeded += value; }
            remove { _model.LogoutSucceeded -= value; }
        }

        public event EventHandler EventAdded
        {
            add { _model.EventAdded += value; }
            remove { _model.EventAdded -= value; }
        }

        public event EventHandler EventModified
        {
            add { _model.EventModified += value; }
            remove { _model.EventModified -= value; }
        }

        public event EventHandler EventDeleted
        {
            add { _model.EventDeleted += value; }
            remove { _model.EventDeleted -= value; }
        }
        #endregion

        public EventReminderController(MonthForm monthForm)
        {
            _month = monthForm;
            _model = new EventReminderModel();
            _modifyingEvent = null;
        }

        internal void ShowLoginDialog()
        {
            _login = new LoginDialog(this);
            _login.ShowDialog(); // modal
        }

        internal void Logout()
        {
            _model.Logout();
        }

        #region LoginDialog Methods
        internal void AttemptLogin(string userName, string password)
        {
            // validate username and password for feasibility (probably over-engineering this...)
            if (!PasswordValidator.GetSingleInstance().ValidatePassword(password) ||
                !PasswordValidator.GetSingleInstance().ValidatePassword(userName))
            {
                MessageBox.Show("Invalid username or password!");
            }
            else
            {
                _model.Login(userName, password);
                _userName = userName;
            }
        }

        internal void OpenRegisterDialog()
        {
            RegisterDialog register = new RegisterDialog(this);
            register.ShowDialog();
        }
        #endregion

        #region RegisterDialog Methods
        internal void AttemptRegister(string username, string password, string password2, string firstname, string lastname, string email)
        {
            // validate the two passwords are the identical
            if (password != password2)
            {
                MessageBox.Show("Passwords do not match!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string message = "";
            if (!RegistrationDataValidator.ValidatePassword(password))
                message += "\tPassword\n";
            if (!RegistrationDataValidator.ValidateUserName(username))
                message += "\tUsername\n";
            if (!RegistrationDataValidator.ValidateFirstName(firstname))
                message += "\tFirst Name\n";
            if (!RegistrationDataValidator.ValidateLastName(lastname))
                message += "\tLast Name\n";
            if (!RegistrationDataValidator.ValidateEmail(email))
                message += "\tEmail Address\n";

            if (message != "")
            {
                message = "The following entries are invalid:\n" + message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else
            {
                _model.Register(username, password, firstname, lastname, email);
            }
        }
        #endregion

        #region MonthForm Methods
        internal void OpenDay(DateTime day)
        {
            DayForm dayForm = new DayForm(this);
            dayForm.Day = day;
            _model.GetEventsThreaded(day);
            dayForm.ShowDialog(); // modal
        }
        #endregion

        #region DayForm Methods
        internal void OpenNewEvent(DateTime date)
        {
            _modifyingEvent = null;
            EventForm form = new EventForm(this);
            form.Date = date;
            form.ShowDialog(); // modal
        }

        internal void OpenModifyEvent(EventData eventData)
        {
            _modifyingEvent = eventData;
            EventForm form = new EventForm(this);
            form.ShowDialog();
        }

        internal void DeleteSelectedEvent(EventData eventData)
        {
            _model.DeleteEvent(eventData);
            // remove from list or raise Events Updated or something...
        }
        #endregion

        #region EventForm Methods
        internal void AcceptEvent(EventData oldEvent, EventData newEvent)
        {
            // validate event?

            // get new event
            if (oldEvent == null)
            {
                // create new event
                _model.SaveNewEvent(newEvent);
            }
            else
            {
                _model.ModifyEvent(oldEvent, newEvent);
            }

            // close event dialog
        }

        internal void AcceptEvent(string title, string descr, DateTime date, object type, string reminder, IEnumerable<string> emails)
        {
            EventData e = new EventData();
            e.Date = date;
            e.Description = descr;
            e.Emails = emails;
            e.Reminder = reminder;
            e.Title = title;
            e.Type = EventTypes.Unknown;

            foreach (EventTypes t in Enum.GetValues(typeof(EventTypes)))
            {
                if (t.ToString() == type)
                {
                    e.Type = t;
                    break;
                }
            }

            if (_modifyingEvent == null)
            {
                _model.ModifyEvent(_modifyingEvent, e);
            }
            else
            {
                _model.SaveNewEvent(e);
            }
        }
        #endregion


    }
}
